<template>
  <div id="import-panel">
    <o-modal
      v-model="isShow"
      :title="$srv.getI18nByPath('vxe.import.impConfirm')"
      :size="modalSize"
      :mask="true"
      :tap-close="false"
      :show-footer="true"
      @on-close="modalClose"
    >
      <div slot="content" class="modal-box">
        <input
          style="display:none"
          ref="fileInput"
          type="file"
          required
          :disabled="inputDisabled"
          @change="onChange"
          @cancel="onCancel"
          accept=".xlsx"
        />
        <div class="body">
          <div class="title-container">
            <div class="open-btn" @click="triggerFileInput">
              <div class="wy-icon wy-wenjianjia4 "></div>
            </div>
            <div class="title">
              <span
                ><span
                  v-if="titleLoading"
                  class="wy-icon wy-repeat loading"
                ></span
                ><span
                  v-else-if="titleSuccess"
                  class="wy-icon wy-success-circle-fill title-success"
                ></span
                ><span
                  v-else-if="titleError"
                  class="wy-icon wy-error-circle-fill title-error"
                ></span
                >{{ $srv.getI18nBySrv(title) }}</span
              >
            </div>
            <div class="file-name">
              <span>{{ openFileName }}</span>
            </div>
          </div>

          <Divider size="small" />
          <div class="progress-content">
            <o-progress :config="cf"></o-progress>
          </div>
        </div>
      </div>
      <div slot="footer" class="footer-container">
        <Button
          type="info"
          ghost
          size="large"
          long
          :disabled="importBtnDisabled"
          :loading="importBtnModaLoading"
          @click="doImport"
          >{{ $srv.getI18nBySrv('导入') }}</Button
        >
        <Button
          type="info"
          ghost
          :class="[reportBtnTip]"
          size="large"
          long
          :disabled="reportBtnDisabled"
          @click="doReport"
          >{{ $srv.getI18nBySrv('报告') }}</Button
        >
      </div>
    </o-modal>
  </div>
</template>

<script lang="ts">
import oModal from '@/components/base/modal/o-modal/index.vue';
import oProgress from '../o-progress-bar/o-progress.vue';
import {
  N_input,
  N_oImportPanel,
  N_oProgressBar,
  T_srv,
  ts,
  Tsrv,
  vue
} from './config';

@T_srv.comp({
  components: {
    oModal,
    oProgress
  }
})
export default class oImportPanel extends vue {
  @T_srv.prop() config: N_oImportPanel.config;

  @T_srv.prop() id: string;

  @T_srv.ref() readonly tempTable!: any;

  cf: N_oProgressBar.I_progressConf = {
    percentage: 0,
    steps: []
  };

  private isShow: boolean = true;

  progressShow: boolean = true;

  modalSize = [600, 190];

  private tempTableName: string = '';

  private importTempTableConfig = null;

  fileContent: File = null;

  titleLoading: boolean = false;

  titleSuccess: boolean = false;

  titleError: boolean = false;

  reportFile = [];

  public formItem = {
    dataHandle: 'insert',
    option: 'import',
    mode: 'strict'
  };

  public importUploadParams = {
    dbName: Tsrv.getDBName(),
    params: null
  };

  private importSettingID = null;

  title: string = 'title';

  private lastLoadTime: number = 0;

  private lastLoaded: number = 0;

  public inputDisabled: boolean = false;

  importBtnModaLoading: boolean = false;

  importBtnDisabled: boolean = true;

  reportBtnDisabled: boolean = true;

  openFileName: string = '';

  private routeID: string = Tsrv.utils.custUUID();

  private disableList = {
    upload: false,
    setting: true,
    check: true
  };

  private funName: string = '';

  private importing: any = null;

  private isImportError: boolean = false;

  get reportBtnTip() {
    if (this.reportBtnDisabled) {
      return '';
    }
    if (!this.reportBtnDisabled) {
      if (this.isImportError) {
        return 'report-tip-error';
      }
      return 'report-tip-success';
    }
    return '';
  }

  created() {
    this.init();
  }

  mounted() {
    this.$bus.$on(this.routeID, e => {
      this.excelEvent(e);
    });
  }

  destroyed() {
    this.$bus.$off(this.routeID);
  }

  public init() {
    this.funName = this.config.funName;
    this.tempTableName = '';
    this.importTempTableConfig = null;
    this.importSettingID = null;
    this.lastLoadTime = 0;
    this.lastLoaded = 0;
    this.disableList = {
      upload: false,
      setting: true,
      check: true
    };
    this.show();
  }

  public show() {
    this.isShow = true;
  }

  public hide() {
    this.isShow = false;
  }

  public modalClose() {
    this.hide();
    this.$bus.$emit(`modal_${this.id}`, this.id);
  }

  private importCheck() {
    if (this.importSettingID !== null) {
      const params = {
        pFuncName: this.funName,
        pTmpTableName: this.tempTableName,
        pModalID: this.importSettingID
      };
      const msg = this.$Message.loading({
        // content: "文件检查中...",
        content: `${Tsrv.getI18nByPath('oimportpanel.filechecking')}···`,
        duration: 0
      });
      const startTime = new Date().getTime();
    }
  }

  private getColumnStyle() {
    if (this.importSettingID !== null && this.tempTableName !== '') {
      const params = {
        partName: `t_ItemInPutFormat`,
        pageNo: 1,
        pageSize: 100,
        filter: `FInputID=${this.importSettingID}`,
        sort: ''
      };
    }
  }

  private importBeforeUpload(file) {
    this.disableList.upload = true;
    if (this.funName) {
      // 只传一次
      const obj = {
        funInfo: [{ funName: this.funName, fileName: file.name }],
        lang: this.$i18n.locale || Tsrv.globalVar.i18n.enUS,
        type: 'import',
        wsCliID: Tsrv.getWsCliID(),
        dataHandle: this.formItem.dataHandle,
        option: this.formItem.option,
        mode: this.formItem.mode
      };
      this.importUploadParams.params = JSON.stringify(obj);
      this.importUploadParams.dbName = Tsrv.getDBName();

      this.lastLoadTime = new Date().getTime();
      this.lastLoaded = 0;
      return true;
    }
    return false;
  }

  private doImport(e: any) {
    this.titleLoading = true;
    this.importBtnModaLoading = true;
    this.cf.percentage = 0;
    if (this.fileContent?.size === 0) {
      this.importBtnDisabled = true;
      return;
    }
    const upload = new ts.T_uploadArg(Tsrv.getWsCliID());
    upload.setFiles([this.fileContent]).setType('import');
    upload.addFunInfo({
      funName: this.funName,
      fileName: this.fileContent.name
    });
    upload
      .setOption('import')
      .setDataHandle('insert')
      .setMode('strict')
      .SetRouteID(this.routeID);

    if (!upload.chkParams()) {
      this.$msg(Tsrv.getI18nByValue('上传参数验证不通过'));
      this.resetState();
      this.importBtnDisabled = false;
      this.importBtnModaLoading = false;
      this.titleLoading = false;
      return;
    }
    Tsrv.upLoad(upload, true)
      .then(([res, err]) => {
        this.$msg(err ?? res.msg);
        if (res.success) {
          const d: N_input.I_fileValue = {
            fileLibID: '',
            files: []
          };
          res.data.forEach(ele => {
            d.files.push({
              _content_: 'file',
              fileName: ele.sourceFileName,
              libFileName: ele.targetFileName
            });
          });
          this.importBtnDisabled = true;
        } else {
          this.isImportError = true;
        }
        this.importBtnModaLoading = false;
        this.titleLoading = false;
      })
      .catch(err => {
        this.$msg(err.message);
        this.resetState();
        this.importBtnModaLoading = false;
        this.titleLoading = false;
        this.isImportError = true;
      });
  }

  public onChange(event: any) {
    this.titleLoading = true;
    const file = event.target.files[0];
    if (!file) return;
    // 验证文件类型
    if (!file.name.endsWith('.xlsx')) {
      this.$msg('请上传.xlsx格式的文件!');
      this.resetState();
      return;
    }
    if (file.size >= 20 * 1024 * 1024) {
      this.$msg('文件内容大于20M');
      this.resetState();

      return;
    }
    this.cf.percentage = 0;
    // 创建 FileReader
    const reader = new FileReader();

    reader.onloadstart = () => {
      this.setTitle('正在读取文件...');
    };

    // 2. 读取中（进度）
    reader.onprogress = e => {
      if (e.lengthComputable) {
        const percent = Math.round((e.loaded / e.total) * 100);
        this.cf.percentage = percent;
        this.setTitle(`读取中... ${percent}%`);
      }
    };

    //  3. 读取成功完成
    reader.onload = e => {
      this.cf.percentage = 100;
      this.fileContent = file;
      this.importBtnDisabled = false;
      this.isImportError = false;
      this.setTitle(`读取完成`);
      this.openFileName = `[${this.formatFileName(file.name)}]`;
      this.titleLoading = false;
    };

    //  4. 读取失败
    reader.onerror = () => {
      this.setTitle('读取失败');
      this.resetState();
      console.error('FileReader 错误:', reader.error);
    };

    //  5. 无论成功失败，最终都会触发
    reader.onloadend = () => {
      // console.log('读取结束（成功或失败）');
      // 可用于隐藏 loading，或允许重新选择
    };

    reader.readAsArrayBuffer(file);
  }

  public onCancel() {
    this.resetState();
  }

  public resetState() {
    const refFileInput: any = this.$refs.fileInput;
    this.fileContent = null;
    refFileInput.value = '';
    this.progressBarInit();
    this.title = 'title';
    this.importBtnDisabled = true;
    this.openFileName = '';
    this.reportFile = [];
    this.reportBtnDisabled = true;
    this.titleLoading = false;
    this.titleSuccess = false;
    this.titleError = false;
  }

  public triggerFileInput() {
    this.resetState();
    this.setTitle('正在打开文件...');
    this.titleLoading = true;
    const refFileInput: any = this.$refs.fileInput;
    refFileInput.click();
  }

  private closeImportMsg() {
    if (this.importing !== null) {
      this.importing();
      this.importing = null;
    }
  }

  private progressBarInit() {
    this.cf = {
      percentage: 0,
      steps: []
    };
  }

  private setTitle(title: string) {
    this.title = title;
  }

  private excelEvent(e: any) {
    this.cf.percentage = e.percentage;
    this.cf.steps = e.steps;
    let exists = false;
    for (const item of e.steps) {
      if (item.status === 'processing') {
        this.setTitle(item.name);
        this.titleLoading = true;
        this.titleSuccess = !this.titleLoading;
        this.titleError = !this.titleLoading;
        exists = true;
      } else if (item.status === 'error') {
        this.titleError = true;
        this.titleSuccess = !this.titleError;
        this.titleLoading = !this.titleError;
      } else if (item.status === 'success') {
        this.titleSuccess = true;
        this.titleLoading = !this.titleSuccess;
        this.titleError = !this.titleSuccess;
      }
    }
    if (!exists) {
      this.setTitle(e.steps[e.steps.length - 1].name);
    }
    if (!Tsrv.noValue(e?.resp?.data)) {
      const rData = atob(e.resp.data);
      const rJson = JSON.parse(rData);
      this.$msg(e.resp.msg);
      this.reportBtnDisabled = Tsrv.noValue(rJson.report);
      if (!this.reportBtnDisabled) {
        this.reportFile = rJson.report;
      }
    }
    if (Tsrv.utils.has(e, 'resp.msg') && !e?.resp?.success) {
      this.isImportError = true;
    }
  }

  private formatFileName(filename: string): string {
    // 匹配最后一个 . 后的内容作为扩展名
    const extMatch = filename.match(/\.([^.]+)$/);
    const extension = extMatch ? `.${extMatch[1]}` : '';
    const nameWithoutExt = filename.slice(0, -extension.length);

    // 总显示长度限制（例如 20）
    const maxLength = 20;

    // 如果整个文件名不超长，直接返回
    if (filename.length <= maxLength) {
      return filename;
    }

    // 计算可用的主名显示长度：maxLength - 省略号(3) - 扩展名长度
    const availableLength = maxLength - 3 - extension.length;

    // 如果可用长度 <= 0，说明扩展名太长，直接截取整体（保险）
    if (availableLength <= 0) {
      return `${filename.slice(0, maxLength - 3)}...${extension}`;
    }

    // 截取主名部分
    const truncatedName = nameWithoutExt.slice(0, availableLength);

    // 拼接：主名... + 扩展名
    return `${truncatedName}...${extension}`;
  }

  doReport() {
    if (!Tsrv.noValue(this.reportFile)) {
      this.reportFile.forEach(fileName => {
        const dwn = new ts.T_downloadArg();
        dwn.setFileName(fileName).setPath('temp');

        Tsrv.download(dwn, true, fileName)
          .then(r => {
            if (r.err) {
              this.$msg(r.err);
            }
          })
          .catch(err => {
            this.$msg(err);
          });
      });
    }
  }
}
</script>

<style lang="scss" scoped>
#import-panel {
  .modal-box {
    height: 100%;
    .body {
      padding: 0 10px;
      ::v-deep .ivu-divider-horizontal {
        margin: 6px 0;
      }
      .title-container {
        display: flex;
        .open-btn {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          width: 28px;
          background: #edf2fa;
        }
        .open-btn:hover {
          cursor: pointer;
          color: #2d8eff;
        }
        .title {
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          background: #f8f8f8;
          // margin-left: 6px;
          // font-size: 24px;
          .loading {
            color: #2d8eff;
            display: inline-block; /* 重要：transform 对 inline 元素有效 */
            animation: rotate 1s linear infinite;
            transform-origin: center; /* 旋转中心在中间 */
            margin-right: 6px; /* 和文字之间加点间距 */
          }
          @keyframes rotate {
            0% {
              transform: rotate(0deg);
            }
            100% {
              transform: rotate(360deg);
            }
          }
          .title-error {
            color: #ce0a10;
          }
          .title-success {
            color: #06b82d;
          }
        }

        .file-name {
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          background: #f8f8f8;
        }
      }
    }
  }
  .footer-container {
    display: flex;

    .report-tip-error {
      position: relative;
      &::after {
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        content: '╳';
        position: absolute;
        top: 0;
        right: 0;
        width: 35%;
        height: 50%;
        background-color: #e74c3c;
        border-radius: 50%;
        transform: translate(50%, -20%);
      }
    }
    .report-tip-success {
      position: relative;
      &::after {
        display: flex;
        justify-content: center;
        align-items: center;
        color: white;
        content: '√';
        position: absolute;
        top: 0;
        right: 0;
        width: 35%;
        height: 50%;
        background-color: #06b82d;
        border-radius: 50%;
        transform: translate(50%, -20%);
      }
    }
  }

  ::v-deep .o-modal .front .box .footer {
    justify-content: center;
  }
}
</style>
